/**********************************************************************************
// DemoXbox360
// 
// Creation:	17 Apr 2011
// Updated:		27 May 2011
// Compiler:	Visual Studio 2011
//
// Notes:		Test the Xinput functions for the Xbox360 Controller
//
**********************************************************************************/

#define WIN32_LEAN_AND_MEAN  // just say no to MFC

#include "Resources.h"
#include "Anabele.h"	
#include <list>
using std::list;

/**********************************************************************************/
/*                          Xbox360Demo Class                                       */
/**********************************************************************************/

class Xbox360Demo: public D3DGame
{
private:
	Sprite * demobox;
	Sprite * demobar;

	SceneManager scene;
	Input input;

	bool keyboardOn;
	bool mouseOn;
	bool xbox360On;

	Circle circ;
	Poly   plane;

	char text[256];
	bool viewBR;

public:
	Xbox360Demo();
	void InitObjects();

	void GameInit();
	void GameLogic();
	void GameDraw();
	void GameShutDown();
	void UnloadResources();
	void LoadResources();
};

/**********************************************************************************/

Xbox360Demo::Xbox360Demo()
{
	viewBR     = false;
	keyboardOn = false;
	mouseOn    = false;
	xbox360On = false;
}

/**********************************************************************************/
void Xbox360Demo::InitObjects()
{
	Point vlist[24] = {Point(1,11),
                          Point(2,8),
						  Point(1,7),
						  Point(1,-1),
						  Point(3,-1),
						  Point(3,-2),
						  Point(11,-3),
						  Point(11,-6),
						  Point(3,-7),
						  Point(2,-8),
						  Point(1,-8),
						  Point(1,-7),
						  Point(-1,-7),
						  Point(-1,-8),
						  Point(-2,-8),
						  Point(-3,-7),
						  Point(-11,-6),
						  Point(-11,-3),
						  Point(-3,-2),
						  Point(-3,-1),
						  Point(-1,-1),
						  Point(-1,7),
						  Point(-2,8),
						  Point(-1, 11)};

	circ = Circle(200.0f);
	plane = Poly(vlist, 24);
	plane.Scale(8.0f, 8.0f);
	
	circ.MoveTo(GetWindowWidth()/2.0f, GetWindowHeight()/2.0f);
	plane.MoveTo(GetWindowWidth()/2.0f, GetWindowHeight()/2.0f);
}

/**********************************************************************************/

void Xbox360Demo::GameInit()
{
	Point p1 = Point(1,1);
	Point p2 = Point(2,2);
	p2=p1;

	srand(GetTickCount());

	InitObjects();

	input.Initialize();

	keyboardOn = input.InitializeKeyboard();
	mouseOn    = input.InitializeMouse();
	xbox360On  = input.InitializeXbox360();

	scene.RegisterStatic(circ);
	scene.RegisterMoving (plane);

	LoadResources();
}

/**********************************************************************************/

void Xbox360Demo::LoadResources()
{
	demobox = new Sprite("Resources/demoBox.png");
	demobox->MoveTo(155, 100);
	
	demobar = new Sprite("Resources/demoBar.png");
	demobar->MoveTo(GetWindowWidth()/2.0f, GetWindowHeight()-30.0f);
}

/**********************************************************************************/

void Xbox360Demo::UnloadResources()
{
	if (demobar) delete demobar;
	if (demobox) delete demobox;
}

/**********************************************************************************/

void Xbox360Demo::GameShutDown()
{
	UnloadResources();
}


/**********************************************************************************/

void Xbox360Demo::GameLogic()
{
	circ.color = Color(255,255,255);
	plane.color = Color(255,255,255);

	// Quits by pressing ESC
	EndsOnEscape();

	// ==== Keyboard input ====
	if (keyboardOn)
	{
		// Update keyboard state
		input.GetKeyboardState();

		// Restart Game (R)
		if (input.KeyPressed(DIK_R))
			InitObjects();

		// Enable Bounding Box (E)
		if (input.KeyPressed(DIK_E))
			viewBR = true;

		// Disable Bounding Box (D)
		if (input.KeyPressed(DIK_D))
			viewBR = false;

		// Scale (A and S)
		if (input.KeyPressed(DIK_A)) // scale up
			plane.Scale(1.1f, 1.1f);
		if (input.KeyPressed(DIK_S)) // scale down
			plane.Scale(0.9f, 0.9f);

		// Rotate (Z and X)
		if (input.KeyPressed(DIK_Z)) // rotate left
			plane.Rotate(-5);
		if (input.KeyPressed(DIK_X)) // rotate right
			plane.Rotate(5);

		// Translate 
		// (Right, Left, Up and Down)
		if (input.KeyPressed(DIK_RIGHT)) // translate right
			plane.Translate(10,0);
		if (input.KeyPressed(DIK_LEFT))  // translate left
			plane.Translate(-10,0);    
		if (input.KeyPressed(DIK_UP))    // translate up
			plane.Translate(0,-10); 
		if (input.KeyPressed(DIK_DOWN))  // translate down
			plane.Translate(0,10);
	}


	// ==== Mouse input ====
	if (mouseOn)
	{
		// Update mouse state
		input.GetMouseState();

		// Translate (mouse movement)
		plane.Translate(input.MouseAxis(MouseAxisX)*2.0f, input.MouseAxis(MouseAxisY)*2.0f);

		// Scale (mouse wheel)
		if (input.MouseAxis(MouseWheel)>0)
			plane.Scale(1.1f,1.1f);
		if (input.MouseAxis(MouseWheel)<0)
			plane.Scale(0.9f,0.9f);

		// Rotate (mouse buttons)
		if (input.MouseButton(MouseLeftButton))
			plane.Rotate(-10.0f);
		if (input.MouseButton(MouseRightButton))
			plane.Rotate(10.0f);

		// Fire (mouse middle button)
		if (input.MouseButton(MouseMiddleButton))
			InitObjects();
	}

	// ==== Joystick input ====
	if (xbox360On)
	{
		// Update joystick state
		input.GetXbox360State();
	
		// Vibration with trigger values
		input.Xbox360Vibrate(0, input.Xbox360Trigger(LTtrigger)*257, input.Xbox360Trigger(RTtrigger)*257);
			
		// Safe Stop Vibration
		if (input.Xbox360Button(BackButton))
			input.Xbox360Vibrate(0,0,0);

		// Start button resets
		if (input.Xbox360Button(StartButton))
			InitObjects();

		// Translate (left analog stick)
		plane.Translate(input.Xbox360ThumbStick(LXthumb)/5000.0f, -1 * input.Xbox360ThumbStick(LYthumb)/5000.0f);
		
		// Translate with DPAD
		if (input.Xbox360Button(DpadUp))
			plane.Translate(0.0f, -10.0f);	// go up
		else if (input.Xbox360Button(DpadDown))
			plane.Translate(0.0f, 10.0f);	// go down

		if (input.Xbox360Button(DpadLeft))
			plane.Translate(-10.0f, 0.0f); // go left
		else if (input.Xbox360Button(DpadRight))
			plane.Translate(10.0f, 0.0f); // go right

		// Scale (LB  and RB)
		if (input.Xbox360Button(LeftShoulder))
			plane.Scale(1.1f,1.1f);
		if (input.Xbox360Button(RightShoulder))
			plane.Scale(0.9f,0.9f);

		// Rotate (right analog stick)
		plane.Rotate(input.Xbox360ThumbStick(RXthumb)/5000.0f);
		plane.Rotate(input.Xbox360ThumbStick(RYthumb)/5000.0f);

		// Enable Bounding Box (A)
		if (input.Xbox360Button(Abutton))
			viewBR = true;

		// Disable Bounding Box (B)
		if (input.Xbox360Button(Bbutton))
			viewBR = false;

		// Enable Bounding Box (X)
		if (input.Xbox360Button(Xbutton))
			viewBR = true;

		// Disable Bounding Box (Y)
		if (input.Xbox360Button(Ybutton))
			viewBR = false;
	}

	
	// test for collision
	if (scene.CollisionDetection())
	{
		pair<GameObject*,GameObject*> pairObjs;

		while ((pairObjs = scene.OnCollisionObjects()) != pair<GameObject*,GameObject*>(nullptr,nullptr))
		{
			((Geometry*) pairObjs.first)->color = Color(65,250,0);
			((Geometry*) pairObjs.second)->color = Color(65,250,0);
		}
	}
} 

/**********************************************************************************/

void Xbox360Demo::GameDraw()
{
	// Lock Screen for pixel plotting functions
	LockScreen();

	// Draw polygons
	circ.Draw();
	plane.Draw();
				
	// Draw the bounding boxes
	if (viewBR)
	{
		plane.GetBBox().color = Color(255,40,70);
		plane.GetBBox().Draw();
	}

	UnLockScreen();

	demobox->Draw();
	demobar->Draw();

	sprintf_s(text, "Xbox360 Demo");
	sysFont->Draw(55, 40, text);

	sprintf_s(text, "Xbox 360 Controller Input");
	sysFont->Draw(55, 80, text);

	sprintf_s(text, "<E> - Enable the bounding box");
	sysFont->Draw(55, 100, text);

	sprintf_s(text, "<D> - Disable the bounding box");
	sysFont->Draw(55, 120, text);
	
	sprintf_s(text, "<R> - Restart");
	sysFont->Draw(55, 140, text);

	sprintf_s(text, "<A> and <S> Scale   <Z> and <X> Rotate   <Arrows> Translate");
	sysFont->Draw(0, GetWindowHeight()-37.0f, text, Color(255,255,255), GetWindowWidth(), 30, DT_CENTER);

	if (xbox360On)
	{
		sprintf_s(text, "Xbox 360 Controller");
		sysFont->Draw(40, 200, text);	

		sprintf_s(text, "DPAD Up: %d", input.Xbox360Button(DpadUp));
		sysFont->Draw(40, 220, text);	
		sprintf_s(text, "DPAD Down: %d", input.Xbox360Button(DpadDown));
		sysFont->Draw(40, 240, text);
		sprintf_s(text, "DPAD Left: %d", input.Xbox360Button(DpadLeft));
		sysFont->Draw(40, 260, text);
		sprintf_s(text, "DPAD Right: %d", input.Xbox360Button(DpadRight));
		sysFont->Draw(40, 280, text);
		sprintf_s(text, "Start: %d", input.Xbox360Button(StartButton));
		sysFont->Draw(40, 300, text);
		sprintf_s(text, "Back: %d", input.Xbox360Button(BackButton));
		sysFont->Draw(40, 320, text);
		sprintf_s(text, "Left Thumb: %d", input.Xbox360Button(LeftThumb));
		sysFont->Draw(40, 340, text);
		sprintf_s(text, "Right Thumb: %d", input.Xbox360Button(RightThumb));
		sysFont->Draw(40, 360, text);
		sprintf_s(text, "LB Shoulder: %d", input.Xbox360Button(LeftShoulder));
		sysFont->Draw(40, 380, text);
		sprintf_s(text, "RB Shoulder: %d", input.Xbox360Button(RightShoulder));
		sysFont->Draw(40, 400, text);
		sprintf_s(text, "A Button: %d", input.Xbox360Button(Abutton));
		sysFont->Draw(40, 420, text);
		sprintf_s(text, "B Button: %d", input.Xbox360Button(Bbutton));
		sysFont->Draw(40, 440, text);
		sprintf_s(text, "X Button: %d", input.Xbox360Button(Xbutton));
		sysFont->Draw(40, 460, text);
		sprintf_s(text, "Y Button: %d", input.Xbox360Button(Ybutton));
		sysFont->Draw(40, 480, text);
		sprintf_s(text, "LT Trigger: %d", input.Xbox360Trigger(LTtrigger));
		sysFont->Draw(40, 500, text);
		sprintf_s(text, "RT Trigger: %d", input.Xbox360Trigger(RTtrigger));
		sysFont->Draw(40, 520, text);
		sprintf_s(text, "LX ThumbStick: %d", input.Xbox360ThumbStick(LXthumb));
		sysFont->Draw(40, 540, text);
		sprintf_s(text, "LY ThumbStick: %d", input.Xbox360ThumbStick(LYthumb));
		sysFont->Draw(40, 560, text);
		sprintf_s(text, "RX ThumbStick: %d", input.Xbox360ThumbStick(RXthumb));
		sysFont->Draw(40, 580, text);
		sprintf_s(text, "RY ThumbStick: %d", input.Xbox360ThumbStick(RYthumb));
		sysFont->Draw(40, 600, text);


	}	
} 



/**********************************************************************************/
/*                                  WinMain                                       */
/**********************************************************************************/

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	Xbox360Demo xdemo;

	//xdemo.SetWindowWidth(1024);
	//xdemo.SetWindowHeight(768);
	//xdemo.SetWindowMode(WINDOWED);
	xdemo.SetWindowBgColor(10,25,55);
	xdemo.SetWindowTitle(string("Xbox 360 Demo"));
	xdemo.SetWindowIcon(LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)));
	xdemo.ShowWindowCursor(false);
	xdemo.Initialize(hInstance);
	xdemo.Start();
	
	return 0;

}

/**********************************************************************************/